﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Threading;

using System.Collections;
using System.IO;
using System.Security.Cryptography;
using System.Runtime.Serialization.Formatters.Binary;
using System.Diagnostics;

namespace DirectoryChecker
{
    struct Config
    {
        public const int MAX_TICKET = 10;
        public const string SNAPSHOOT_NAME = @"\kz.dat";
    }

    struct WorkOption
    {
        public string ExeFileName;
        public string DataFileName;
        public string Path;
        public bool Size;
        public bool Md5;
        public bool Save;
    }

    [Serializable]
    struct FileSnapshoot
    {
        public bool IsFile;
        public long Size;
        public string Name;
        public string Md5;
    }

    delegate void Notify_Delegate(string info);

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string dir = Application.StartupPath;
            textBox1.Text = dir;
            textBox2.Text = dir;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                textBox1.Text = textBox2.Text = folderBrowserDialog1.SelectedPath;
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {
                textBox1.Text = textBox2.Text = folderBrowserDialog1.SelectedPath;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            WorkOption wo;
            wo.ExeFileName = Application.ExecutablePath;
            wo.DataFileName = Application.StartupPath + Config.SNAPSHOOT_NAME;
            wo.Path = textBox1.Text.Trim();
            wo.Size = checkBox1.Checked;
            wo.Md5 = checkBox2.Checked;
            wo.Save = false;

            if (string.IsNullOrEmpty(wo.Path))
            {
                MessageBox.Show("请选择目录");
                return;
            }
            if (wo.Path.EndsWith("\\"))
            {
                wo.Path = wo.Path.TrimEnd('\\');
            }
            if (!Directory.Exists(wo.Path))
            {
                MessageBox.Show("文件夹不存在！");
                return;
            }
            if (!File.Exists(wo.DataFileName))
            {
                MessageBox.Show("快照不存在！");
                return;
            }

            button3.Enabled = false;
            toolStripStatusLabel1.Text = "校验开始";
            listBox1.Items.Clear();

            Worker worker = new Worker();
            worker.OnSnapshootShow += (info1) =>
            {
                this.BeginInvoke(new Notify_Delegate((info2) =>
                {
                    toolStripStatusLabel1.Text = info2;
                }), info1);
            };
            worker.OnSnapshootComplete += (info1) =>
            {
                this.BeginInvoke(new Notify_Delegate((info2) =>
                {
                    listBox1.Items.Add(info2);
                    toolStripStatusLabel1.Text = "校验中...";
                }), info1);
            };
            worker.OnCheckShow += (info1) =>
            {
                this.BeginInvoke(new Notify_Delegate((info2) =>
                {
                    listBox1.Items.Add(info2);
                    listBox1.TopIndex = listBox1.Items.Count - (int)(listBox1.Height / listBox1.ItemHeight);
                }), info1);
            };
            worker.OnCheckComplete += (info1) =>
            {
                this.BeginInvoke(new Notify_Delegate((info2) =>
                {
                    button3.Enabled = true;
                    toolStripStatusLabel1.Text = info2;
                }), info1);
            };

            Thread th = new Thread(new ParameterizedThreadStart(worker.startCheck));
            th.Name = "startCheck";
            th.IsBackground = true;
            th.Start(wo);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            WorkOption wo;
            wo.ExeFileName = Application.ExecutablePath;
            wo.DataFileName = Application.StartupPath + Config.SNAPSHOOT_NAME;
            wo.Path = textBox2.Text.Trim();
            wo.Size = checkBox3.Checked;
            wo.Md5 = checkBox4.Checked;
            wo.Save = true;

            if (string.IsNullOrEmpty(wo.Path))
            {
                MessageBox.Show("请选择目录");
                return;
            }
            if (wo.Path.EndsWith("\\"))
            {
                wo.Path = wo.Path.TrimEnd('\\');
            }
            if (!Directory.Exists(wo.Path))
            {
                MessageBox.Show("文件夹不存在！");
                return;
            }
            if (File.Exists(wo.DataFileName))
            {
                if (DialogResult.Yes != MessageBox.Show("快照已存在，是否覆盖？", "覆盖确认", MessageBoxButtons.YesNo, MessageBoxIcon.Warning))
                {
                    return;
                }
            }

            button4.Enabled = false;
            toolStripStatusLabel1.Text = "快照开始";
            Worker worker = new Worker();
            worker.OnSnapshootShow += (info1) =>
            {
                this.BeginInvoke(new Notify_Delegate((info2) =>
                {
                    toolStripStatusLabel1.Text = info2;
                }), info1);
            };
            worker.OnSnapshootComplete += (info1) =>
            {
                this.BeginInvoke(new Notify_Delegate((info2) =>
                {
                    button4.Enabled = true;
                    toolStripStatusLabel1.Text = info2;
                }), info1);
            };

            Thread th = new Thread(new ParameterizedThreadStart(worker.startSnapshoot));
            th.Name = "startSnapshoot";
            th.IsBackground = true;
            th.Start(wo);
        }

        private void listBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Control && e.KeyCode == Keys.C && listBox1.SelectedItems.Count > 0)
            {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < listBox1.SelectedItems.Count; i++)
                {
                    sb.Append(listBox1.SelectedItems[i]);
                    if (i < listBox1.SelectedItems.Count - 1)
                    {
                        sb.Append("\r\n");
                    }
                }
                Clipboard.Clear();
                Clipboard.SetText(sb.ToString());
            }
            if (e.Control && e.KeyCode == Keys.A)
            {
                for (int i = 0; i < listBox1.Items.Count; i++)
                {
                    listBox1.SetSelected(i, true);
                }
            }
        }
    }
}
